package com.it001.filter;

import cn.hutool.core.io.IoUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSON;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author 程序员恰恰
 * @date 2023-07-31 17:10
 */
public class SecureRequestWrapper extends HttpServletRequestWrapper {

    private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVmKHd9sDQ9QIZoZuYgqVwhBaBODbuSbSaCK71\n" +
            "xyDhxtORaLeZCqFHd1tjTs2Qm9l9O9HeqYChhX7hJD/fVYMWDFlOT0z1PVW5gNLhGIbEBuo4vWDR\n" +
            "h3hxC0GobUPRJwvUzkYca+sZv2LrfVua+Ot04M+0YR3Cq9AK01+4SrIGfwIDAQAB";

    private static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJWYod32wND1Ahmhm5iCpXCEFoE4\n" +
            "Nu5JtJoIrvXHIOHG05Fot5kKoUd3W2NOzZCb2X070d6pgKGFfuEkP99VgxYMWU5PTPU9VbmA0uEY\n" +
            "hsQG6ji9YNGHeHELQahtQ9EnC9TORhxr6xm/Yut9W5r463Tgz7RhHcKr0ArTX7hKsgZ/AgMBAAEC\n" +
            "gYAwu+aPjuFFsWubugAccQNAYmeKdSu/+Rbyzz1gKBzYMJOf3UNiggoEZCfLdFKXd44ktCYsqX+U\n" +
            "Hw80fUCpmwv21CXpzXXgdtcv3wzRwfQqTxsrxoXOQ721ovq0TVfmId9592LdS1LNvtrfcuOQwfLr\n" +
            "nn/H9cyn0yfA33ouUtQQkQJBAOATVrXvcuL/aLsB76r8wLvWHASC0GicunSq9z4JlG5d02w5Odwb\n" +
            "3qe5JPrBaB7ap2Dv7sd35S0v/CfvZ3cG9d0CQQCq6NMVR8JTh9ouudblNOBQN397DGwzy1FIekJL\n" +
            "Zy8y3nMRXg2thWdXirdPFBNeyCUJv+UwRFBd/eVJiNnX+u4LAkB0u95qfcoeU+zdr86KB47ozExg\n" +
            "VT35odzJNuADI75+GMcyFEX+U06VljCbqfJyUHruV1DP/bgY6Gy26VO/gJLJAkEAloYoIn3o8Jid\n" +
            "2LlkQsqnJP88D6uJQLS5ChRjfvWJ5Et3HLyxXzo3IirR95u+06OCu2t+91uzTJTo9DLLaiVesQJB\n" +
            "ANYd/TqScl3qgRacTdits0grtKwFua+q12wk8Ve3F4DzoJfMmDqyYrX9p7W+lZuX9mVPnIE1EhIe\n" +
            "ivy5GQ7IfLU=";
    /**
     * 定义一个字节数组的成员变量,记录解密以后的数据
     */
    private byte[] DECODE_USER_INFO = null;

    public SecureRequestWrapper(HttpServletRequest request) {
        super(request);

        try {
            //获取输入流
            ServletInputStream inputStream = request.getInputStream();
            //创建一个内存输出流对象,用来保存前端所传递过来的数据
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            IoUtil.copy(inputStream, byteArrayOutputStream);
            //从byteArrayOutputStream 对象中获取前端传递过来的数据
            String transferData = byteArrayOutputStream.toString("utf-8");
            //System.out.println(transferData);

            //把tranferData 转换成Map
            Map<String, String> map = JSON.parseObject(transferData, Map.class);
            String content = map.get("content");
            String aesKey = map.get("aesKey");
            //对aesKey进行解密操作
            RSA rsa = SecureUtil.rsa(PRIVATE_KEY, PUBLIC_KEY);
            String decryptStr = rsa.decryptStr(aesKey, KeyType.PrivateKey, Charset.defaultCharset());
            //System.out.println(decryptStr);

            //对content数据进行解密
            AES aes = SecureUtil.aes(decryptStr.getBytes(StandardCharsets.UTF_8));
            String userInfo = aes.decryptStr(content, Charset.defaultCharset());
            //System.out.println(userInfo);
            this.DECODE_USER_INFO = userInfo.getBytes(StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            //定义一个内存操作的输入流对象,去关联DECODE_USER_INFO
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(DECODE_USER_INFO);

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
}
